﻿using Devonline.AspNetCore;
using Devonline.Entity;
using Microsoft.Extensions.Logging;

namespace Devonline.Database.NoSQL;

/// <summary>
/// NoSQL 数据库服务的默认抽象实现
/// </summary>
public abstract class NoSQLDataService(ILogger<NoSQLDataService> logger, IDatabaseEndpoint endpoint) : INoSQLDataService
{
    /// <summary>
    /// 日志
    /// </summary>
    protected readonly ILogger<NoSQLDataService> _logger = logger;
    /// <summary>
    /// 数据库连接终结点配置
    /// </summary>
    protected readonly IDatabaseEndpoint _endpoint = endpoint;

    /// <summary>
    /// 写入一行数据到数据库
    /// </summary>
    /// <typeparam name="TModel">数据对象模型的类型</typeparam>
    /// <param name="model">待写入的数据</param>
    /// <returns></returns>
    public virtual Task WriteAsync<TModel>(TModel model) where TModel : class, new()
    {
        throw new NotImplementedException();
    }
    /// <summary>
    /// 写入多行数据到数据库
    /// </summary>
    /// <typeparam name="TModel">数据对象模型的类型</typeparam>
    /// <param name="data">待写入的数据</param>
    /// <returns></returns>
    public virtual Task WritesAsync<TModel>(IEnumerable<TModel> data) where TModel : class, new()
    {
        throw new NotImplementedException();
    }

    /// <summary>
    /// 从数据库查询多行数据
    /// </summary>
    /// <typeparam name="TModel">数据对象模型的类型</typeparam>
    /// <typeparam name="TQueryRequest">查询请求表达式类型</typeparam>
    /// <param name="request">查询请求</param>
    /// <returns></returns>
    public virtual Task<IEnumerable<TModel>> QueryAsync<TModel, TQueryRequest>(TQueryRequest request) where TModel : class, new() where TQueryRequest : PagedRequest
    {
        throw new NotImplementedException();
    }

    /// <summary>
    /// 执行循环写入
    /// </summary>
    /// <param name="action">要执行的具体写入方法</param>
    /// <returns></returns>
    protected async Task ExecuteWriteAsync(Func<Task> action)
    {
        var retry = 0;
        var success = false;
        while (!success && retry++ <= _endpoint.Retry)
        {
            try
            {
                _logger.LogDebug("将写入数据库 {host} 中", _endpoint.Host);
                await action();
                _logger.LogInformation("已写入数据库 {host}", _endpoint.Host);
                success = true;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "将数据写入数据库 {host} 时出错!", _endpoint.Host);
            }
        }

        if (!success)
        {
            _logger.LogError("将数据写入数据库 {host} 时失败, 且经过 {retry} 次重新尝试均不能成功, 本次写入操作请检查问题后再做处理!", _endpoint.Host, _endpoint.Retry);
        }
    }
}